#include<iostream>
using namespace std;
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>

void CleanupChild(int signo)
{
    if(signo == SIGCHLD)
    {
        while(true)
        {
            pid_t rid = waitpid(-1, nullptr, WNOHANG);  //非阻塞等待回收任意一个
            if(rid > 0)
            {
                cout<<"wait success pid:"<<rid<<endl;
            }
            else
            {
                cout<<"wait child process failed"<<endl;
                break;
            }
        }
    }
    cout<<"wait sub process done"<<endl;
}

int main()
{
    signal(SIGCHLD, CleanupChild);  //子进程退出会发送一个SIGCHLD信号给父进程，只是默认动作是忽略而已
    //现在自定义捕捉，让其自动回收创建的子进程.
    for(int i = 0;i<100;i++)
    {
        pid_t id = fork();
        if(id == 0)
        {
            //child
            int cnt = 5;
            while(cnt--)
            {
                cout<<"I am a child process"<<"pid:"<<getpid()<<endl;
                sleep(1);
            }
            cout<<"child process dead"<<endl;
            exit(0);
        }
    }
    //father
    while(true)
        sleep(1);
    return 0;
}

// void Print(sigset_t& pending)
// {
//     for(int signo = 31;signo>=1;signo--)
//     {
//         if(sigismember(&pending, signo))
//             cout<<"1";
//         else    
//             cout<<"0";
//     }
//     cout<<endl;
// }

// void handler(int signo)
// {
//     cout<<"signal:"<<signo<<endl;
//     //不断获取当前进程的pending信号集合
//     sigset_t pending;
//     sigemptyset(&pending);
//     while(true)
//     {
//         sigpending(&pending);
//         Print(pending);
//         sleep(1);
//     }
// }

// int main()
// {
//     cout<<"pid: "<<getpid()<<endl;
//     struct sigaction act, oact;
//     act.sa_flags = 0;
//     act.sa_handler = handler;
//     sigemptyset(&act.sa_mask);
//     sigaddset(&act.sa_mask, 3);     //3， 4， 5号信号都屏蔽
//     sigaddset(&act.sa_mask, 4);
//     sigaddset(&act.sa_mask, 5);
//     sigaction(2, &act, &oact);      //相当于signal, 捕捉自定义递达处理
//     while(true) sleep(1);
//     return 0;
// }